package com.whfc.emp.manager.impl;

import com.alibaba.fastjson.JSON;
import com.whfc.common.exception.BizException;
import com.whfc.common.face.szyc.AddPersons;
import com.whfc.common.face.szyc.DelPersons;
import com.whfc.common.face.szyc.PersonInfo;
import com.whfc.common.face.szyc.SzycConst;
import com.whfc.common.file.FileHandler;
import com.whfc.common.geometry.Point;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.third.map.MapApi;
import com.whfc.common.third.map.MapLoc;
import com.whfc.common.util.DateUtil;
import com.whfc.emp.dao.AppEmpMapper;
import com.whfc.emp.dao.AppFaceGateMapper;
import com.whfc.emp.dao.AppFaceGatePersonMapper;
import com.whfc.emp.entity.AppEmp;
import com.whfc.emp.entity.AppFaceGate;
import com.whfc.emp.entity.AppFaceGateConfig;
import com.whfc.emp.entity.AppFaceGatePerson;
import com.whfc.emp.enums.TaskType;
import com.whfc.emp.manager.FaceGateManager;
import com.whfc.emp.mqtt.MqttConfig;
import com.whfc.emp.param.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 海清视讯 MQTT
 *
 * @author qzexing
 * @version 1.0
 * @date 2022/1/18 18:25
 */
@Service("mqttHqsxFaceGateManagerImpl")
public class MqttHqsxFaceGateManagerImpl implements FaceGateManager {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AppFaceGatePersonMapper appFaceGatePersonMapper;

    @Autowired
    private AppEmpMapper appEmpMapper;

    @Autowired
    private FileHandler fileHandler;

    @Autowired(required = false)
    private MqttConfig.MqttMessageSender mqttMessageSender;

    @Value("${mqtt.enabled}")
    private Boolean mqttEnable;

    @Autowired
    private AppFaceGateMapper appFaceGateMapper;

    @Autowired(required = false)
    private MessageProducer messageProducer;

    @Autowired
    private MapApi mapApi;

    @Override
    public void info(AppFaceGateConfig appFaceGateConfig) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(AppFaceGateAddParam request) {
        String deviceKey = request.getDeviceKey();
        String name = request.getName();
        Integer deptId = request.getDeptId();
        Point point = request.getPoint();

        AppFaceGate record = new AppFaceGate();
        record.setDeviceKey(deviceKey);
        record.setDeptId(deptId);
        record.setName(name);
        record.setDirection(request.getDirection());
        record.setPlatform(request.getPlatform());
        // 增加闸机位置信息
        if (point != null) {
            Double lat = point.getLat();
            Double lng = point.getLng();
            MapLoc loc = mapApi.geocode(lng, lat);
            record.setLng(lng);
            record.setLat(lat);
            record.setAddress(loc.getAddress());
        }
        appFaceGateMapper.insertSelective(record);
        if (mqttEnable) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "未开启MQTT，无法增加闸机");
        }
        //订阅闸机主题
        MqttPahoMessageDrivenChannelAdapter adapter = (MqttPahoMessageDrivenChannelAdapter) messageProducer;
        String rec = MessageFormat.format(SzycConst.TOPIC_REC, deviceKey);
        adapter.addTopic(rec, 0);
        // 回复平台
        String ack = MessageFormat.format(SzycConst.TOPIC_ACK, deviceKey);
        adapter.addTopic(ack, 0);
        // 陌生人抓拍记录
        String snap = MessageFormat.format(SzycConst.TOPIC_SNAP, deviceKey);
        adapter.addTopic(snap, 0);
        // 二维码扫码信息
        String qrCode = MessageFormat.format(SzycConst.TOPIC_QRCODE, deviceKey);
        adapter.addTopic(qrCode, 0);
    }

    @Override
    public void del(Integer faceGateId) {
        Integer count = appFaceGatePersonMapper.countByFaceGateId(faceGateId);
        if (count > 0) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该闸机下还有人员未销权，不能删除！");
        }
        appFaceGateMapper.deleteLogicById(faceGateId);
    }

    @Override
    public String faceGateGrantEmdAdd(FaceGateGrantEmdAddParam request) {
        String deviceKey = request.getDeviceKey();
        PersonInfo personInfo = handlerEmpInfo(request.getFaceGateId(), deviceKey, request.getEmpId());
        List<PersonInfo> list = new ArrayList<>();
        list.add(personInfo);
        // 发送批量同步人员的MQ消息
        String topic = MessageFormat.format(SzycConst.TOPIC_REQ, deviceKey);
        AddPersons addPersons = new AddPersons(list);
        String payload = JSON.toJSONString(addPersons);
        mqttMessageSender.sendToMqtt(topic, 0, payload);
        return null;
    }

    @Override
    public String faceGateGrantEmdImgAdd(FaceGateGrantEmdImgAddParam request) {
        return null;
    }

    @Override
    public String faceGateGrantEmdAuth(FaceGateGrantEmdAuthParam request) {
        return null;
    }

    @Override
    public void faceGateBatchGrantEmpAuth(AppFaceGateGrantEmpParam request) {
        if (mqttEnable == null || !mqttEnable) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "MQTT暂未启用");
        }
        List<Integer> empIdList = request.getEmpIdList();
        if (empIdList == null || empIdList.isEmpty()) {
            return;
        }
        Integer faceGateId = request.getFaceGateId();
        String deviceKey = request.getDeviceKey();
        List<PersonInfo> list = new ArrayList<>();
        for (Integer empId : empIdList) {
            PersonInfo personInfo = handlerEmpInfo(faceGateId, deviceKey, empId);
            if (personInfo != null) {
                list.add(personInfo);
            }
        }

        // 发送批量同步人员的MQ消息
        String topic = MessageFormat.format(SzycConst.TOPIC_REQ, deviceKey);
        AddPersons addPersons = new AddPersons(list);
        String payload = JSON.toJSONString(addPersons);
        mqttMessageSender.sendToMqtt(topic, 0, payload);
    }


    @Override
    public void faceGateRevokeEmp(AppFaceGateGrantEmpParam request) {
        if (mqttEnable == null || !mqttEnable) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "MQTT暂未启用");
        }
        List<Integer> empIdList = request.getEmpIdList();
        if (empIdList == null || empIdList.isEmpty()) {
            return;
        }
        Integer faceGateId = request.getFaceGateId();
        AppFaceGate appFaceGate = appFaceGateMapper.selectByPrimaryKey(faceGateId);
        if (appFaceGate == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该闸机不存在");
        }
        String deviceKey = appFaceGate.getDeviceKey();
        List<String> customIds = new ArrayList<>();
        for (Integer empId : empIdList) {
            AppFaceGatePerson appFaceGatePerson = appFaceGatePersonMapper.selectByFaceGateIdAndEmpId(faceGateId, empId);
            if (appFaceGatePerson != null) {
                customIds.add(appFaceGatePerson.getPersonGuid());
                appFaceGatePerson.setTaskType(TaskType.EMP_UN_AUTH.getValue());
                appFaceGatePersonMapper.updateByPrimaryKeySelective(appFaceGatePerson);
            }
        }
        // 发送批量同步人员的MQ消息
        String topic = MessageFormat.format(SzycConst.TOPIC_REQ, deviceKey);
        DelPersons delPersons = new DelPersons(customIds);
        String payload = JSON.toJSONString(delPersons);
        mqttMessageSender.sendToMqtt(topic, 0, payload);

    }

    @Override
    public String deviceAuthorizationPerson(String deviceKey, String name, String imgUrl) {
        return null;
    }

    @Override
    public String deviceAuthorizationCancel(String deviceKey, String personGuid) {
        return null;
    }

    @Override
    public void openDoor(String deviceKey) {

    }

    @Override
    public void sync(Integer faceGateId) {

    }

    @Override
    public String getToken() {
        return null;
    }

    /**
     * 处理人员信息
     *
     * @param faceGateId 闸机ID
     * @param deviceKey  闸机序列号
     * @param empId      人员ID
     */
    private PersonInfo handlerEmpInfo(Integer faceGateId, String deviceKey, Integer empId) {
        StringBuilder message = new StringBuilder();
        boolean flag = true;
        // 验证人员是否存在
        AppEmp appEmp = appEmpMapper.selectByPrimaryKey(empId);
        if (appEmp == null) {
            return null;
        }
        // 验证人员头像
        String avatar = appEmp.getAvatar();
        if (StringUtils.isBlank(avatar)) {
            flag = false;
            message.append("人员头像不存在");
        } else {
            // 验证文件大小
            String ossKey = fileHandler.getPath(avatar);
            Long fileSize = fileHandler.getFileSize(ossKey);
            // 图片不超过1M
            long maxLength = 1024 * 1024;
            if (fileSize < 1 || fileSize >= maxLength) {
                flag = false;
                message.append(" 人员头像不超过1M");
            }
        }

        // 获取 EmpCode
        String empCode = appEmp.getEmpCode();
        if (empCode == null || StringUtils.isBlank(empCode.trim())) {
            empCode = UUID.randomUUID().toString().replace("-", "");
            appEmp.setEmpCode(empCode);
            appEmpMapper.updateByPrimaryKeySelective(appEmp);
        }

        //验证是否重复授权
        AppFaceGatePerson faceGatePerson = appFaceGatePersonMapper.selectByFaceGateIdAndEmpId(faceGateId, empId);
        if (faceGatePerson != null) {
            Integer taskType = faceGatePerson.getTaskType();
            if (TaskType.EMP_AUTH.getValue().equals(taskType)) {
                // 人员授权已完成跳过
                return null;
            }
            Date updateTime = faceGatePerson.getUpdateTime();
            Date now = new Date();
            // 计算上一次认证间隔 单位 秒
            int intervals = Math.toIntExact(Math.abs((now.getTime() - updateTime.getTime()) / 1000));
            // 最大间隔 10分钟
            int maxIntervals = 10 * 60;
            if (TaskType.NOT_START.getValue().equals(taskType) && intervals < maxIntervals) {
                // 小于10分钟的授权先跳过
                flag = false;
                message.append(" 人员授权间隔需要10分钟");
            }
            faceGatePerson.setMessage(message.toString());
            appFaceGatePersonMapper.updateByPrimaryKeySelective(faceGatePerson);
        } else {
            faceGatePerson = new AppFaceGatePerson();
            faceGatePerson.setDeptId(appEmp.getDeptId());
            faceGatePerson.setDeviceKey(deviceKey);
            faceGatePerson.setFaceGateId(faceGateId);
            faceGatePerson.setEmpId(empId);
            faceGatePerson.setPersonGuid(empCode);
            faceGatePerson.setTaskType(TaskType.NOT_START.getValue());
            faceGatePerson.setMessage(message.toString());
            appFaceGatePersonMapper.insertSelective(faceGatePerson);
        }
        // 有异常则跳过当前
        if (!flag) {
            return null;
        }

        PersonInfo personInfo = new PersonInfo();
        personInfo.setCustomId(empCode);
        personInfo.setName(appEmp.getEmpName());
        personInfo.setNation(1);
        Integer gender = appEmp.getGender();
        // 转换为玉川的性别
        gender = gender == 2 ? 1 : 0;
        personInfo.setGender(gender + "");
        personInfo.setPersonId(appEmp.getIdCardNo());
        personInfo.setTelnum1(appEmp.getPhone());
        personInfo.setAddress(appEmp.getAddress());
        String birthday = null;
        if (appEmp.getBirthday() != null) {
            birthday = DateUtil.formatDate(appEmp.getBirthday());
        }
        personInfo.setBirthday(birthday);
        personInfo.setPicUri(avatar);
        personInfo.setPersonType("0");
        personInfo.setTempCardType("0");
        personInfo.setIsCheckSimilarity("1");
        return personInfo;
    }
}
